{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Processing in IPython\n",
    "\n",
    "This notebook shows the ability to use the Processing library (based on Java). There is also a full [Processing kernel](https://github.com/Calysto/calysto_processing) that does a Java-compile (showing any errors) with additional benefits. This magic does no error checking.\n",
    "\n",
    "Requirements:\n",
    "\n",
    "* IPython/Jupyter notebook\n",
    "* [metakernel](https://github.com/Calysto/metakernel)\n",
    "* Internet connection\n",
    "\n",
    "First you need to install metakernel:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "! pip install metakernel --user"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, you should enable metakernel magics for IPython:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from metakernel import register_ipython_magics\n",
    "register_ipython_magics()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, you are ready to embed Processing sketches in your notebook. Try moving your mouse over the sketch:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<canvas id=\"canvas_1\"></canvas>\n",
       "<script>\n",
       "require([window.location.protocol + \"//calysto.github.io/javascripts/processing/processing.js\"], function () {\n",
       "    var processingCode = '\\nvoid draw() {\\n    background(128);\\n    ellipse(mouseX, mouseY, 10, 10);\\n}';\n",
       "    var cc = Processing.compile(processingCode);\n",
       "    var processingInstance = new Processing(\"canvas_1\", cc);\n",
       "});\n",
       "</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%processing\n",
    "\n",
    "void draw() {\n",
    "    background(128);\n",
    "    ellipse(mouseX, mouseY, 10, 10);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This example from https://processing.org/examples/clock.html :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<canvas id=\"canvas_2\"></canvas>\n",
       "<script>\n",
       "require([window.location.protocol + \"//calysto.github.io/javascripts/processing/processing.js\"], function () {\n",
       "    var processingCode = \"\\nint cx, cy;\\nfloat secondsRadius;\\nfloat minutesRadius;\\nfloat hoursRadius;\\nfloat clockDiameter;\\n\\nvoid setup() {\\n  size(640, 360);\\n  stroke(255);\\n  \\n  int radius = min(width, height) / 2;\\n  secondsRadius = radius * 0.72;\\n  minutesRadius = radius * 0.60;\\n  hoursRadius = radius * 0.50;\\n  clockDiameter = radius * 1.8;\\n  \\n  cx = width / 2;\\n  cy = height / 2;\\n}\\n\\nvoid draw() {\\n  background(0);\\n  \\n  // Draw the clock background\\n  fill(80);\\n  noStroke();\\n  ellipse(cx, cy, clockDiameter, clockDiameter);\\n  \\n  // Angles for sin() and cos() start at 3 o'clock;\\n  // subtract HALF_PI to make them start at the top\\n  float s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI;\\n  float m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI; \\n  float h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI;\\n  \\n  // Draw the hands of the clock\\n  stroke(255);\\n  strokeWeight(1);\\n  line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius);\\n  strokeWeight(2);\\n  line(cx, cy, cx + cos(m) * minutesRadius, cy + sin(m) * minutesRadius);\\n  strokeWeight(4);\\n  line(cx, cy, cx + cos(h) * hoursRadius, cy + sin(h) * hoursRadius);\\n  \\n  // Draw the minute ticks\\n  strokeWeight(2);\\n  beginShape(POINTS);\\n  for (int a = 0; a < 360; a+=6) {\\n    float angle = radians(a);\\n    float x = cx + cos(angle) * secondsRadius;\\n    float y = cy + sin(angle) * secondsRadius;\\n    vertex(x, y);\\n  }\\n  endShape();\\n}\";\n",
       "    var cc = Processing.compile(processingCode);\n",
       "    var processingInstance = new Processing(\"canvas_2\", cc);\n",
       "});\n",
       "</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%processing\n",
    "\n",
    "int cx, cy;\n",
    "float secondsRadius;\n",
    "float minutesRadius;\n",
    "float hoursRadius;\n",
    "float clockDiameter;\n",
    "\n",
    "void setup() {\n",
    "  size(640, 360);\n",
    "  stroke(255);\n",
    "  \n",
    "  int radius = min(width, height) / 2;\n",
    "  secondsRadius = radius * 0.72;\n",
    "  minutesRadius = radius * 0.60;\n",
    "  hoursRadius = radius * 0.50;\n",
    "  clockDiameter = radius * 1.8;\n",
    "  \n",
    "  cx = width / 2;\n",
    "  cy = height / 2;\n",
    "}\n",
    "\n",
    "void draw() {\n",
    "  background(0);\n",
    "  \n",
    "  // Draw the clock background\n",
    "  fill(80);\n",
    "  noStroke();\n",
    "  ellipse(cx, cy, clockDiameter, clockDiameter);\n",
    "  \n",
    "  // Angles for sin() and cos() start at 3 o'clock;\n",
    "  // subtract HALF_PI to make them start at the top\n",
    "  float s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI;\n",
    "  float m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI; \n",
    "  float h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI;\n",
    "  \n",
    "  // Draw the hands of the clock\n",
    "  stroke(255);\n",
    "  strokeWeight(1);\n",
    "  line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius);\n",
    "  strokeWeight(2);\n",
    "  line(cx, cy, cx + cos(m) * minutesRadius, cy + sin(m) * minutesRadius);\n",
    "  strokeWeight(4);\n",
    "  line(cx, cy, cx + cos(h) * hoursRadius, cy + sin(h) * hoursRadius);\n",
    "  \n",
    "  // Draw the minute ticks\n",
    "  strokeWeight(2);\n",
    "  beginShape(POINTS);\n",
    "  for (int a = 0; a < 360; a+=6) {\n",
    "    float angle = radians(a);\n",
    "    float x = cx + cos(angle) * secondsRadius;\n",
    "    float y = cy + sin(angle) * secondsRadius;\n",
    "    vertex(x, y);\n",
    "  }\n",
    "  endShape();\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Try it out!"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.4.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
